/**
 * @author Johann Prieur
 */
package mygui;

import javax.swing.*;
import javax.swing.border.*;
import javax.swing.tree.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

import kernel.*;
import objects.*;
import utils.*;

public class BaseProperties extends Properties {

    private Simulator _kernel;
    private BaseStation _station;
    private JTabbedPane _tabs;
    private GeneralPanel _general;
    private EmissionsPanel _emissions;
    private ProbesPanel _probes;
    private DataBaseStation _data;

    public BaseProperties(BaseStation station)
    {
	_kernel = Simulator.getSimulator();
	_station = station;
	_data = (DataBaseStation)_station.getProperties();

	setTitle("Base station properties");

 	_tabs = new JTabbedPane(JTabbedPane.TOP,
 				JTabbedPane.SCROLL_TAB_LAYOUT);
 	
	_general = new GeneralPanel(_kernel, _data, _station);
	_emissions = new EmissionsPanel(_data);
	_probes = new ProbesPanel(_data);
 	_tabs.add(_general, "General");
 	_tabs.add(_emissions, "Emissions");
 	_tabs.add(_probes, "Probes");

	add("North", new ObjectIdCard(Type.base,
				      _data.getName(),
				      "Base station"));
	add("Center", _tabs);
	pack();
	WindowUtilities.centerFrame(this);
	setVisible(true);
    }
    
    public void apply()
    {
	_general.apply();
	_emissions.apply();
	_probes.apply();
	_station.setProperties(_data);

	if(_general.getMakeModelSelected()){
	    ModelManager.getModelManager().addModel(_general.getModelName(),_data);
	}
    }

    private class GeneralPanel extends JPanel implements ActionListener
    {
	private Simulator _kernel;
	private BaseStation _station;
	private DataBaseStation _data;

        private JTextField _name;
	private String _name_tip = "Name of the base station";

	private JSpinner _x;
	private String _x_tip = "x coordinate of the station";

	private JSpinner _y;
	private String _y_tip = "y coordinate of the station";

	private JSpinner _max_reach_length;
	private String _max_reach_length_tip = "Wave length in meters";

	private JSpinner _carrier_rate;
	private String _carrier_rate_tip = "Carrier rate.\n" +
	    "Must be upper or equal to 1.0";

	private JCheckBox _make_model;
	private String _make_model_tip = "Convert into model";
	
	private JSpinner _max_frequency;
	private String _max_frequency_tip = "Maximum communication frequency";

	private JSpinner _min_frequency;
	private String _min_frequency_tip = "Minimum communication frequency";

	private JTextField _model_name;
	private String _model_name_tip = "Model name";

	
	private GeneralPanel(Simulator kernel,
			     DataBaseStation data,
			     BaseStation station)
	{
	    _kernel = kernel;
	    _data = data;
	    _station = station;
	    setLayout(new BorderLayout());
	    
	    JPanel general = new JPanel();	    
	    general.setLayout(new GridLayout(8,2,4,4));
	    general.setBorder(new EmptyBorder(4,4,4,4));

	    _name = new JTextField(_data.getName());
	    if(_kernel.isWished(_station)){
		_name.setEnabled(false);
	    }

	    _x = new JSpinner(new SpinnerNumberModel(_data.getCoordX(),
						     DataBaseStation.COORD_X_MIN,
						     Simulator.getSimulator().getEnvironment().getSpace().getWidth(),
						     1));
	    _y = new JSpinner(new SpinnerNumberModel(_data.getCoordY(),
						     DataBaseStation.COORD_Y_MIN,
						     Simulator.getSimulator().getEnvironment().getSpace().getHeight(),
						     1));
	    _carrier_rate = new JSpinner(new SpinnerNumberModel());

	    double max = Math.max(Simulator.getSimulator().getEnvironment().getSpace().getWidth(),
			   Simulator.getSimulator().getEnvironment().getSpace().getHeight());
	    _max_reach_length = new JSpinner(new SpinnerNumberModel(_data.getMaxReachRadius(),
 								    DataBaseStation.MAX_REACH_RADIUS_MIN,
 								    max, 1));
 	    _carrier_rate = new JSpinner(new SpinnerNumberModel(_data.getCarrierRate(),
								DataBaseStation.CARRIER_RATE_MIN,
								max, 1));

	    _min_frequency = new JSpinner(new SpinnerNumberModel(_data.getFmin(),
								 DataBaseStation.FMIN_MIN,
								 DataBaseStation.FMIN_MAX,
								 1));
	    _max_frequency = new JSpinner(new SpinnerNumberModel(_data.getFmax(),
								 DataBaseStation.FMAX_MIN,
								 DataBaseStation.FMAX_MAX,
								 1));

	    _make_model = new JCheckBox(_make_model_tip,false);
	    _model_name = new JTextField("");

	    general.add(new JLabel("Name"));
	    general.add(_name);
	    _name.setToolTipText(_name_tip);

	    general.add(new JLabel("x location"));
	    general.add(_x);
	    _x.setToolTipText(_x_tip);

	    general.add(new JLabel("y location"));
	    general.add(_y);
	    _y.setToolTipText(_y_tip);

	    general.add(new JLabel("Max reach length"));
	    general.add(_max_reach_length);
	    _max_reach_length.setToolTipText(_max_reach_length_tip);

	    general.add(new JLabel("Carrier rate"));
	    general.add(_carrier_rate);		
	    _carrier_rate.setToolTipText(_carrier_rate_tip);

	    general.add(new JLabel("Min communication frequency"));
	    general.add(_min_frequency);
	    _min_frequency.setToolTipText(_min_frequency_tip);

	    general.add(new JLabel("Max communication frequency"));
	    general.add(_max_frequency);
	    _max_frequency.setToolTipText(_max_frequency_tip);

	    general.add(_make_model);
	    _make_model.setToolTipText(_make_model_tip);
	    _make_model.addActionListener(this);

	    general.add(_model_name);
	    _model_name.setToolTipText(_model_name_tip);
	    _model_name.setEnabled(false);

	    add("North", general);
	}
	
	public boolean getMakeModelSelected(){
	    return _make_model.isSelected();
	}

	public String getModelName(){
	    return _model_name.getText();
	}
	
	public void apply()
	{
	    _data.setName(_name.getText());
	    _data.setCoordX(((Double)_x.getValue()).doubleValue());
	    _data.setCoordY(((Double)_y.getValue()).doubleValue());
	    _data.setMaxReachRadius(((Double)_max_reach_length.getValue()).doubleValue());
	    _data.setCarrierRate(((Double)_carrier_rate.getValue()).doubleValue());
	    _data.setFmin(((Double)_min_frequency.getValue()).floatValue());
	    _data.setFmax(((Double)_max_frequency.getValue()).floatValue());
	}
	
	public void actionPerformed(ActionEvent e)
	{
	    Component source = (Component)e.getSource();
	    if(source == _make_model)
		{
		    _model_name.setEnabled(_make_model.isSelected());
		}
	}
    }

    private class EmissionsPanel extends JPanel implements ActionListener
    {
	
	private Simulator _kernel;
	private DataBaseStation _data;

	private JTextField _start_time;
	private String _start_time_tip = "Start time in seconds";

	private JComboBox _stations;
	private String _stations_tip = "Available receivers";

	private JButton _add_receiver;
	private String _add_receiver_tip = "Add a receiver";

	private JButton _remove_receiver;
	private String _remove_receiver_tip = "Remove a receiver";

	private DefaultListModel _model;
	private JList _receiver_list;

	private JTextField _datas;
	private String _datas_tip = "Amount of data to send in bytes";

	private JButton _add;
	private String _add_tip = "Add this emission to the list";

	private JButton _remove;
	private String _remove_tip = "Remove the selected emission from the list";

	private DefaultListModel _model_we;
	private JList _emissions;

	private EmissionsPanel(DataBaseStation data)
	{
	    _kernel = Simulator.getSimulator();
	    _data = data;
	    setLayout(new BorderLayout());
	    
	    JPanel emissions = new JPanel();	    
	    emissions.setLayout(new GridLayout(6,2,4,4));
	    emissions.setBorder(new EmptyBorder(4,4,4,4));

 	    _start_time = new JTextField();

	    Vector receivers = new Vector(_kernel.getBaseStation());
	    receivers.addAll(_kernel.getBaseStation());
	    _stations = new JComboBox(receivers);

	    _datas = new JTextField();
	    
	    _add_receiver = new JButton(UIM.createImageIcon("images/add.png",""));
	    _add_receiver.addActionListener(this);
	    _remove_receiver = new JButton(UIM.createImageIcon("images/remove.png",""));
	    _remove_receiver.addActionListener(this);
	    _model = new DefaultListModel();
	    _receiver_list = new JList(_model);
	    _receiver_list.setVisibleRowCount(5);

	    _add = new JButton(UIM.createImageIcon("images/add.png",""));
	    _add.addActionListener(this);
	    _remove = new JButton(UIM.createImageIcon("images/remove.png",""));
	    _remove.addActionListener(this);

	    _model_we = new DefaultListModel();
	    _emissions = new JList(_model_we);
	    for(Object dwe: _data.getWishedEmission())
		_model_we.addElement(dwe);

	    emissions.add(new JLabel("Start time"));
	    emissions.add(_start_time);
	    _start_time.setToolTipText(_start_time_tip);

	    emissions.add(new JLabel("Available receivers"));
	    emissions.add(_stations);
	    _stations.setToolTipText(_stations_tip);

	    emissions.add(_add_receiver);
	    _add_receiver.setToolTipText(_add_receiver_tip);
	    
	    emissions.add(_remove_receiver);
	    _remove_receiver.setToolTipText(_remove_receiver_tip);

	    emissions.add(new JLabel("Selected receivers"));
	    JScrollPane scroll = new JScrollPane(_receiver_list);
	    scroll.setPreferredSize(new Dimension(100,30));
	    emissions.add(scroll);

	    emissions.add(new JLabel("Amount of data to send"));
	    emissions.add(_datas);
	    _datas.setToolTipText(_datas_tip);

	    emissions.add(_add);
	    _add.setToolTipText(_add_tip);

	    emissions.add(_remove);
	    _remove.setToolTipText(_remove_tip);

	    add("North", emissions);
	    add("Center", new JScrollPane(_emissions));
	}

	public void actionPerformed(ActionEvent e)
	{
	    Component source = (Component)e.getSource();
	    if(source == _add_receiver)
		{
		    _model.addElement((Station)_stations.getSelectedItem());
		}
	    else if(source == _remove_receiver)
		{
		    int index = _receiver_list.getSelectedIndex();
		    if(index != -1) _model.remove(index);
		}
	    else if(source == _add)
		{
		    int starttime = (Integer.decode(_start_time.getText())).intValue() * 1000;
		    Vector<String> dests = new Vector<String>();
		    for(Enumeration elem=_model.elements();elem.hasMoreElements();)
			dests.add(elem.nextElement().toString());
		    Vector<String> params = new Vector<String>();
		    // Maybe add more parameters, just the data size for now
		    params.add(_datas.getText());
		    DataWishedEmission dws = new
			DataWishedEmission(starttime, dests, params);
		    _model_we.addElement(dws);
		}
	    else if(source == _remove)
		{
		    int index = _emissions.getSelectedIndex();
		    if(index != -1) _model_we.remove(index);		    
		}
	}

	public void apply()
	{
	    Vector we = new Vector();
	    for(Enumeration e = _model_we.elements() ; e.hasMoreElements() ;) {
		we.add(e.nextElement());
	    }
	    _data.setWishedEmission(we);
	}
    }

    private class ProbesPanel extends JPanel implements ActionListener {
	
	private Simulator _kernel;
	private DataBaseStation _data;

	private JComboBox _probes;
	private JTextArea _description;
	private JButton _add;
	private JButton _remove;
	private DefaultListModel _model;
	private JList _list;

	private ProbesPanel(DataBaseStation data)
	{
	    _kernel = Simulator.getSimulator();
	    _data = data;
	    setLayout(new BorderLayout());

	    JPanel top = new JPanel(new BorderLayout());
	    JPanel toptop = new JPanel(new GridLayout(1,2,0,0));
	    JPanel topbot = new JPanel(new GridLayout(1,2,0,0));
	    top.add("North", toptop);
	    top.add("South", topbot);

	    Vector<String> strat_labels = new Vector();

	    StrategyChoser scCom = new StrategyChoser("results");
	    scCom.checkSuperclass("ProbeCom");
	    Vector<Class> stratsCom = scCom.getStrategies();

	    for(Class strat : stratsCom){
		String[] path = strat.toString().split("[.]");
		strat_labels.add(path[path.length-1]);
	    }
	    _probes = new JComboBox(strat_labels);
    
	    // No way to fill the description field, its contain was hardcoded
	    // in the older version and this way to handle probes as strings sucks.
	    // We should deal with Class objects, cast them into Probe and have a static
	    // way to grab the probe description.
	    _add = new JButton(UIM.createImageIcon("images/add.png",""));
	    _add.addActionListener(this);
	    _remove = new JButton(UIM.createImageIcon("images/remove.png",""));
	    _remove.addActionListener(this);
	    _model = new DefaultListModel();
	    _list = new JList(_model);
	    for(Object probe: _data.getProbes())
		_model.addElement(probe);

	    toptop.add(new JLabel("Probe types"));
	    toptop.add(_probes);
	    topbot.add(_add);
	    topbot.add(_remove);
	    
	    add("North", top);
	    add("Center", new JScrollPane(_list));
	}   

	public void actionPerformed(ActionEvent e)
	{
	    Component source = (Component)e.getSource();
	    if(source == _add)
		{
		    _model.addElement((String)_probes.getSelectedItem());
		}
	    else if(source == _remove)
		{
		    int index = _list.getSelectedIndex();
		    if(index != -1) _model.remove(index);
		}
	}

	public void apply()
	{
	    Vector probes = new Vector();
	    for(Enumeration e = _model.elements() ; e.hasMoreElements() ;) {
		probes.add(e.nextElement());
	    }
	    _data.setProbes(probes);
	}
    }
    
//     private class GeneralPanel extends JPanel 
//     {
// 	/**
// 	 * Name
// 	 */
// 	private JTextField _name;
// 	private String _name_tip = "Name of the base station";

// 	/**
// 	 * Wave length
// 	 */
// 	private JSpinner _wave_length;
// 	private String _wave_length_tip = "Wave length in meters";

// 	/**
// 	 * Carrier rate
// 	 */
// 	private JSpinner _carrier_rate;
// 	private String _carrier_rate_tip = "Carrier rate.\n" +
// 	    "Must be upper or equal to 1.0";

// 	private GeneralPanel()
// 	{
// 	    setLayout(new BorderLayout());
	    
// 	    JPanel general = new JPanel();	    
// 	    general.setLayout(new GridLayout(3,2,4,4));
// 	    general.setBorder(new EmptyBorder(4,4,4,4));

// 	    _name = new JTextField();
// 	    _wave_length = new JSpinner(new SpinnerNumberModel());
// 	    _carrier_rate = new JSpinner(new SpinnerNumberModel());

// 	    general.add(new JLabel("Name"));
// 	    general.add(_name);
// 	    _name.setToolTipText(_name_tip);

// 	    general.add(new JLabel("Wave length"));
// 	    general.add(_wave_length);
// 	    _wave_length.setToolTipText(_wave_length_tip);

// 	    general.add(new JLabel("Carrier rate"));
// 	    general.add(_carrier_rate);		
// 	    _carrier_rate.setToolTipText(_carrier_rate_tip);

// 	    add("North", general);								
// 	}
//     }

//     private class EmissionsPanel extends JPanel {
	
// 	private JSpinner _start_time;
// 	private String _start_time_tip = "Start time in seconds";

// 	private JComboBox _stations;
// 	private String _stations_tip = "Available receivers";

// 	private JSpinner _data;
// 	private String _data_tip = "Amount of data to send in bytes";

// 	private JButton _add;
// 	private String _add_tip = "Add this emission to the list";

// 	private JButton _remove;
// 	private String _remove_tip = "Remove the selected emission from the list";

// 	private JList _emissions;

// 	private EmissionsPanel()
// 	{
// 	    setLayout(new BorderLayout());
	    
// 	    JPanel emissions = new JPanel();	    
// 	    emissions.setLayout(new GridLayout(4,2,4,4));
// 	    emissions.setBorder(new EmptyBorder(4,4,4,4));

// 	    _start_time = new JSpinner(new SpinnerNumberModel());
// 	    _stations = new JComboBox();
// 	    _data = new JSpinner(new SpinnerNumberModel());

// 	    _add = new JButton(new ImageIcon(ConstantsIcons.add_16x16));
// 	    _remove = new JButton(new ImageIcon(ConstantsIcons.remove_16x16));
	    
// 	    _emissions = new JList();

// 	    emissions.add(new JLabel("Start time"));
// 	    emissions.add(_start_time);
// 	    _start_time.setToolTipText(_start_time_tip);

// 	    emissions.add(new JLabel("Available receivers"));
// 	    emissions.add(_stations);
// 	    _stations.setToolTipText(_stations_tip);

// 	    emissions.add(new JLabel("Amount of data to send"));
// 	    emissions.add(_data);
// 	    _data.setToolTipText(_data_tip);

// 	    emissions.add(_add);
// 	    _add.setToolTipText(_add_tip);

// 	    emissions.add(_remove);
// 	    _remove.setToolTipText(_remove_tip);

// 	    add("North", emissions);
// 	    add("Center", new JScrollPane(_emissions));
// 	}

//     }

//     private class ProbesPanel extends JPanel {
	
// 	private ProbesPanel()
// 	{
// 	    setLayout(new BorderLayout());
	    
// 	    JPanel probes = new JPanel();	    
// 	    probes.setLayout(new GridLayout(3,2,4,4));
// 	    probes.setBorder(new EmptyBorder(4,4,4,4));

// 	    // TODO

// 	    add("North", probes);
// 	}

//     }
    
}